\chapter{Cross compilation}
\label{chap-cross-compilation}

In this chapter, we discuss issues specific to \emph{cross
  compilation}, i.e. when a compiler produces code for a system other
than the host \commonlisp{} system it runs in.  For general
compilation topics, see \refChap{chap-compiler}.  A cross compiler
must necessarily create some external representation, like a
\emph{file}, containing the result of the compilation, and that file
must be readable on the target system.  This file can be in the form
of a target \emph{fasl} file, or, as is the case with \sysname{}
bootstrapping, an entire target executable file.

\section{General issues with cross compilation}

While it may seem obvious and straightforward (though perhaps not
easy) to write a cross compiler for \commonlisp{}, there are some minor issues
that have to be considered. 

We exclude the use of the \texttt{read} function of the host
environment because it can cause some problem.%
\footnote{The main difference that is important to bootstrapping is
  that some implementations use implementation-specific functions in
  the result of the \emph{backquote} reader macro.  This practice is
  explicitly allowed by the standard (Section 2.4.6), and also encouraged
  (Section 2.4.6.1).}
Instead, we use a the Eclector%
\footnote{See \texttt{https://github.com/robert-strandh/Eclector}}
reader, which can be customized in many ways.  In particular, it
allows \emph{source tracking}, i.e. it can associate file position
with every expression in the file.

If the cross compiler generates \emph{fasl} files, then the compiler
is necessarily a \emph{file compiler}, and we face the same
restrictions concerning literal objects as a native file compiler
does.%---------------------------------------------------------
\footnote{See Section 3.2.4 in the standard.}

For either compilation scenario, though, there are some restrictions
due to differences between systems that the standard explicitly allows.

The most important such restriction has to do with floating-point
numbers.  If (say) the host allows for fewer types of floating-point
numbers, then \texttt{read} will not accurately represent the source
code as the native file compiler for the target would.  Code to be
compiled by the cross compiler must therefore either avoid
floating-point literals altogether, or instead use some expression to
create it and make sure that the expression is not evaluated until
load time.  

The other restriction has to do with \emph{potential numbers} which
different systems may define differently.  The easy solution is to
avoid potential numbers in source code.  This should not be hard to
do. 

\section{Environments}

The standard\footnote{See section 3.2.1 of the standard.} gives a list of
the environments that are related to compilation.  We briefly
summarize them here:

\begin{itemize}
\item The \emph{startup environment} is the environment of the image
  from which the compiler was invoked.
\item The \emph{compilation environment} is used to hold information
  that is required by the compiler in order to accomplish its task
  correctly.  Such information consists of definitions and
  declarations that the compiler needs, for instance definitions of
  macros and constant variables,  and declarations such as
  \texttt{inline} or \texttt{special}. 
\item The \emph{evaluation environment} which the standard says is a
  run-time environment in which evaluations by the compiler takes
  place, typically executions of macro expanders, but also any other
  code that is indicated by \texttt{eval-when} to be evaluated at
  compile time.
\item The \emph{run-time environment} in which the program resulting
  from the compilation is eventually executed.
\end{itemize}

The run-time environment is clearly not relevant to cross
compilation. 

For the purpose of cross compilation, it is practical to think of the
startup environment as containing two distinct parts, that we call the
\emph{host startup environment} and the \emph{target startup
  environment}.

The \emph{host startup environment} is the environment of the image
from which the cross compiler was invoked.

The \emph{target startup environment} is the initial compilation
environment, in that it contains definitions and declarations that
must already exist when the cross compiler is invoked.  In \sysname{}
the \emph{target startup environment} is represented explicitly as a
standard object (i.e., an instance of \texttt{standard-object}).
Furthermore, the compilation environment of the cross compiler is the
same as the \emph{target startup environment} so that any side effects
on the compilation environment as a result of the cross compilation
persist after the compilation terminates.  

The relevant functions of the target startup environment are all \commonlisp{}
functions that access or modify the environment, such as
\texttt{fdefinition}, \texttt{proclaim}, \texttt{(setf
  macro-function)}, etc., but also implementation-specific functions
such as functions for accessing and storing type expanders and
\texttt{setf} expanders.

As with other bundles of related functionality, environment
manipulation uses its own package, named \texttt{sicl-environment}.
In the native environment, this package \texttt{use}es the
\texttt{common-lisp} package so that the symbols \texttt{fdefinition},
\texttt{proclaim}, etc. are the imported symbols from the
\texttt{common-lisp} package.  During cross compilation, however,
these symbols are \texttt{shadow}ed by the \texttt{sicl-environment}
package, so that they are distinct from the analogous symbols of the
host \texttt{common-lisp} package.  Symbols naming macros such as
\texttt{declaim} and \texttt{defun}, however, are not
\texttt{shadow}ed, but the resulting expansion code contains symbols
that are qualified by the \texttt{sicl-environment} package.  

Let us take an example.  \refCode{code-defparameter} shows a
simplified implementation of the \texttt{defparameter} macro.  It is
simplified in that it does not handle the documentation. 

\begin{codefragment}
\inputcode{code-defparameter.code}
\caption{\label{code-defparameter}
Simplified definition of the \texttt{defparameter} macro.}
\end{codefragment}

The definition of \refCode{code-defparameter} is established with the
package \texttt{sicl-environment} as the current package.  For that
reason, the symbols \texttt{ensure-defined-variable} and
\texttt{symbol-value} are internal to the \texttt{sicl-environment}
package.  When code that invokes the \texttt{defparameter} macro is
compiled by the cross compiler, the host compiler will evaluate the
form \texttt{(ensure-defined-variable ,name)}.  The result of that
evaluation is that the variable is created in the target startup
environment.  Subsequent compilations by the cross compiler will
``see'' this definition and consider the variable as \texttt{special}.
When the resulting code is loaded into the run-time environment, the
symbol \texttt{symbol-value} in the package \texttt{sicl-environment}
is imported from the package \texttt{common-lisp}.

\section{Compile-time processing of standard macros}

In \refApp{app-all-standard-macros}, we show a complete list of all
the standard \commonlisp{} macros. 

Most of those macros have no side effects at compile time.  They
simply expand to some other code to be processed instead.  Some of
them do, however, expand to \texttt{eval-when} forms that include the
situation \texttt{:compile-toplevel}.  We need to make sure that one
of the following cases applies for those macros:

\begin{itemize}
\item The macro is not used in any top-level form in any file compiled
  by the cross compiler.
\item The cross compiler is able to evaluate the relevant code with
  the analogous side effects as the native file compiler.
\item The cross compiler provides alternative definitions for
  functions that are invoked as a result of compile-time evaluation,
  and those alternative definitions provide enough of the side effects
  to compile all files that are subsequently subject to compilation by
  the cross compiler.
\end{itemize}

The standard \commonlisp{} macros with compile-time side effects are:
\texttt{declaim}, \texttt{defclass}, \texttt{defconstant},
\texttt{defgeneric}, \texttt{define-compiler-macro},
\texttt{define-condition}, \texttt{define-method-combination},
\texttt{define-modify-macro}, \texttt{define-setf-expander},
\texttt{define-symbol-macro}, \texttt{defmacro}, \texttt{defmethod},
\texttt{defpackage}, \texttt{defparameter}, \texttt{defsetf},
\texttt{defstruct}, \texttt{deftype}, \texttt{defun}, \texttt{defvar},
and \texttt{in-package}.

Of those, the following will never appear as top-level forms in any
file compiled by the cross compiler: 

\begin{itemize}
\item \texttt{define-condition}, because the condition system is not
  needed by the cross compiler.
\item \texttt{define-method-combination}.
\item \texttt{defstruct}.
\end{itemize}

The following macros are handled in an analogous way during cross
compilation: \texttt{declaim}, \texttt{defconstant},
\texttt{define-compiler-macro}, \texttt{define-modify-macro},
\texttt{define-setf-expander}, \texttt{define-symbol-macro},
\texttt{defmacro}, \texttt{defparameter}, \texttt{defsetf},
\texttt{deftype}, \texttt{defun}, \texttt{defvar}, and
\texttt{in-package}.

We are left with the following macros: \texttt{defclass}, 
\texttt{defgeneric}, and \texttt{defmethod}.

For \texttt{defclass} the standard says that the \emph{class name} must
be made available for use as a specializer in \texttt{defmethod} and
as the \texttt{:metaclass} option in subsequent invocations of
\texttt{defclass}.  It is thus suggested that \texttt{defmethod}
checks at compile-time that the specializers exist, though the standard
does not mention any such checks. 

The standard also says that if \texttt{find-class} is called with the
relevant environment argument, then the class object should be
returned.  We can think of no need to invoke \texttt{find-class} at
compile time.

Now, according to the specification of the metaobject protocol,
\texttt{defclass} expands to a call to \texttt{ensure-class} (not a
standard \commonlisp{} function).  Our solution is thus to provide a
compile-time version of \texttt{sicl-clos:ensure-class} that only
makes the \emph{class name} available.

For \texttt{defgeneric}, the standard says that the implementation is not
required to perform any compile-time side effects, but that it can
choose to store information about arguments and such if it so wants.
As a consequence, we handle it the same way we handle \texttt{defun}.

For \texttt{defmethod}, the standard says that the implementation is not
required to perform any compile-time side effects.  The
compile-time side effects will be in the case where no prior
\texttt{defgeneric} form has been seen, in which case we store
information about the derived parameters of the implicitly created
generic function.  As suggested by the standard in the description of
\texttt{defclass}, we also verify that the specializer class names
have been previously seen. 


